<?php
/**
 * 获取输入参数 支持过滤和默认值
 * 使用方法:
 * <code>
 * in('id',0);
 * in('name','','htmlspecialchars');
 * in('name/d'); /d: int, /s(default): string, /a: array, /f: float, /b: bool
 * in(); 获取所有
 * </code>
 * @param string $name 变量的名称 支持指定类型
 * @param mixed $default 不存在的时候默认值
 * @param mixed $filter 参数过滤方法
 * @return mixed
 */
function in( $name = null, $default = '', $filter = null ){
    static $_input;
    
    if (is_array($name)) {
        $_input = $name;
        return true;
    }
    
    if( !isset($_input) ){
        $_input = null;
        if ($_POST) {
            $_input = $_POST;
        } else if (strtolower($_SERVER['REQUEST_METHOD']) == 'post' && false !== strstr(strtolower($_SERVER['CONTENT_TYPE']), 'application/json')) {
            $_input = json_decode( file_get_contents('php://input'), true );
        }
        if( !$_input ){
            $_input = [];
        }
    }
    
    if(strpos($name,'/')){ //指定修饰符
        list($name,$type)     =    explode('/',$name,2);
    }
    
    if( '' == $name ){
        $data       =   $_input;
        $filters    =   isset($filter)?$filter:config('DEFAULT_FILTER');
        if($filters) {
            if(is_string($filters)){
                $filters    =   explode(',',$filters);
            }
            foreach($filters as $filter){
                $data   =   array_map_recursive($filter,$data); //参数过滤
            }
        }
    }elseif(isset($_input[$name])) { //取值操作
        $data       =   $_input[$name];
        $filters    =   isset($filter)?$filter:config('DEFAULT_FILTER');
        if($filters) {
            if(is_string($filters)){
                if(0 === strpos($filters,'/')){
                    if(1 !== preg_match($filters,(string)$data)){
                        //支持正则验证
                        return   isset($default) ? $default : null;
                    }
                }else{
                    $filters    =   explode(',',$filters);
                }
            }elseif(is_int($filters)){
                $filters    =   [$filters];
            }
            
            if(is_array($filters)){
                foreach($filters as $filter){
                    if(function_exists($filter)) {
                        $data   =   is_array($data) ? array_map_recursive($filter,$data) : $filter($data); //参数过滤
                    }else{
                        $data   =   filter_var($data,is_int($filter) ? $filter : filter_id($filter));
                        if(false === $data) {
                            return   isset($default) ? $default : null;
                        }
                    }
                }
            }
        }
        
        if(!empty($type)){
            switch(strtolower($type)){
                case 'a':    //数组
                    $data     =    (array)$data;
                    break;
                case 'd':    //数字
                    $data     =    (int)$data;
                    break;
                case 'f':    //浮点
                    $data     =    (float)$data;
                    break;
                case 'b':    //布尔
                    $data     =    (boolean)$data;
                    break;
                case 's':   //字符串
                default:
                    $data   =   (string)$data;
            }
        }
    }else{ //变量默认值
        $data       =    isset($default)?$default:null;
    }
    
    is_array($data) && array_walk_recursive($data,'think_filter');
    
    return $data;
}

function think_filter(&$value){
    // TODO 其他安全过滤
    
    // 过滤查询特殊字符
    if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){
        $value .= ' ';
    }
}

/**
 * 接口输出
 * @param number $code 状态码
 * @param array $data 数据
 * @param array $info_params 提示信息用到的变量
 * @param mixed $debug_info 调试信息，APP_DEBUG开启后有效
 * @param bool $echo 是否输出
 */
function out( $code, $data = [], $info_params = null, $debug_info = null, $echo = true ){
    //不对数据格式化输出
    if ($code === null) {
        exit((string)$data);
    }
    if (null === config('C_STATUS_CODE-'.config('__CONTROLLER_NAME__'))) {
        $path   = APP_PATH.'statuscode/'.strtolower(config('__CONTROLLER_NAME__')).'.php';
        if (file_exists($path)) {
            config('C_STATUS_CODE-'.config('__CONTROLLER_NAME__'), include $path);
        }
        if (null === config('C_STATUS_CODE-'.config('__CONTROLLER_NAME__'))) {
            config('C_STATUS_CODE-'.config('__CONTROLLER_NAME__'), false);
        }
    }
    $status_code = config('C_STATUS_CODE-'.config('__CONTROLLER_NAME__').'.'.$code);
    if (!$status_code) {
        $status_code = config('STATUS_CODE.'.$code);
    }
    if( !$status_code ){
        $status_code = config('STATUS_CODE.error_status_code');
    }
    $result = [
        'status'    => $code,
        'info'        => $info_params !== null ? vsprintf($status_code[1], $info_params) : $status_code[1],
        'data'        => $data,
    ];
    if($result['info'] == null){
        $result['info']    = '';
    }
    if($result['data'] == null){
        $result['data']    = [];
    }
    
    if(APP_DEBUG){
        $result['debug'] = $debug_info !== null ? $debug_info : $code.', '.db()->getLastSql();
    }
    
    // 将要输出的结果throw到swoole里的catch中输出
    if( $echo ){
        $result  = json_encode( $result );
        if (\api\Auth::needCrypt()) {
            $result = \api\Auth::encrypt($result);
        }
        if ($code != 'ok') {
            qLog($result);
        }
        
        exit($result);
    }
    
    return $result;
}

function create_salt($length=12) {
    return $salt = substr(uniqid(rand()),0,$length);
}
function create_md5($string,$salt) {
    return md5($string.$salt);
}
function uuid() {
    $charid = strtolower(md5(uniqid(rand(), true)));
    return substr($charid,0,24);
}

function qLog($message, $with_head = false, $log_dir = '') {
    $log_file_size  = 2097152;
    if (!$log_dir) {
        $log_dir    = RUNTIME_PATH.'logs_debug/';
    }
    // 自动创建日志目录
    if (!is_dir($log_dir)) {
        mkdir($log_dir, 0755, true);
    }
    $destination    = $log_dir.date('y-m-d').'.log';
    // 检测日志文件大小，超过配置大小则备份日志文件重新生成
    if (is_file($destination) && $log_file_size <= filesize($destination)) {
        rename($destination, dirname($destination) . '/' . basename($destination) . '-' . time());
    }
    
    $now = date('c');
    if ($with_head) {
        $message    = "[{$now}] " . $_SERVER['REMOTE_ADDR'] . ' ' . $_SERVER['REQUEST_URI'] . "\r\n{$message}\r\n";
    } else {
        $message    = "[{$now}] {$message}\r\n";
    }
    
    error_log($message, 3, $destination);
}